package design.createModel.singleton;

import java.io.Serializable;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * @author wenhao hu
 * @title: LazySingleton
 * @projectName design
 * @description: TODO
 * @date 2022/2/1813:52
 */
public class LazySingleton implements Serializable {

    private static volatile LazySingleton lazySingleton;

    private static AtomicBoolean flag = new AtomicBoolean(false);

    private LazySingleton(){
        if (flag.get()){
            throw new RuntimeException("不可以创建多个对象");
        }
        flag.set(true);
    }

    private static class SingletonHolder{
        private static final LazySingleton INSTANCE = new LazySingleton();
    }

    //线程不安全
    public static LazySingleton getInstance1(){
        if (lazySingleton == null){
            lazySingleton = new LazySingleton();
        }
        return lazySingleton;
    }
    //线程安全 但效率低
    public static LazySingleton getInstance2(){
        if (lazySingleton == null){
            lazySingleton = new LazySingleton();
        }
        return lazySingleton;
    }

    //线程安全 双重检测
    public static LazySingleton getInstance3(){
        if (lazySingleton == null){
            synchronized (LazySingleton.class){
                if (lazySingleton == null){
                    lazySingleton = new LazySingleton();
                }
            }
        }
        return lazySingleton;
    }

    //静态内部类方式 只有第一次调用的时候系统才会去加载SingletonHolder，并初始化LazySingleton。这样不仅可以保证线程安全，也能保证唯一性。
    public static LazySingleton getInstance4(){
        return SingletonHolder.INSTANCE;
    }

    public enum EnumSingleton {
        INSTANCE;
    }

    //当进行反序列化时会自动调用该方法，该方法的返回值直接返回
    public Object readResolve(){
        return SingletonHolder.INSTANCE;
    }

}
